package com.pactera.asmp.server.common.utils;

import com.pactera.asmp.server.common.logprint.utils.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;

/**
 * @ProjectName: asmpserver
 * @Package: com.pactera.asmp.server.common.utils
 * @ClassName: GradleApkUtil
 * @Author: lvzhiqiang
 * @Description: Gradle编译ASMP_Client源码生成指定项目APK
 * @Date: 2019/8/26 16:38
 * @Version: 1.0
 */
@Configuration
public class GradleApkUtil {

    @Value("${gradle.build.opt}")
    private static String OPT ="asmpclient:assembleRelease" ;
    @Value("${gradle.build.path}")
    private static String GRADLE_PATH  ="C:/Users/Pactera/.gradle/wrapper/dists/gradle-4.1-all/bzyivzo6n839fup2jbap0tjew/gradle-4.1/bin/gradle.bat";
    @Value("${gradle.asmp.build.path}")
    private static String GRADLE_ASMP_PATH  ="E:/CodeSource/ASMP";


    public static void main(String[] args) {
        gradleBuildWork(new IBuildCallBack() {
            @Override
            public void onBuildCallBackStatus(boolean status) {
                System.err.println("Build Task1 :"+ status);
            }
        });
    }

    /**
     * @Method gradleBuildWork
     * @Description gradleBuildWork
     * @param:
     * gradle.build.path = "C:/Users/Pactera/.gradle/wrapper/dists/gradle-4.1-all/bzyivzo6n839fup2jbap0tjew/gradle-4.1/bin/gradle.bat"
     * gradle.build.opt = "asmpclient:assembleRelease"
     * gradle.asmp.build.path="E:/CodeSource/ASMP"
     * @auther: lzq
     * @date: 2019/8/27 14:11
     */
    public static void gradleBuildWork(IBuildCallBack callBack){
        try {
            Process process = Runtime.getRuntime().exec(GRADLE_PATH + StringUtils.SPACE +OPT,null,new File(GRADLE_ASMP_PATH));
            ProcessLogRunnable infoLogRunnable = new ProcessLogRunnable(callBack);
            ProcessLogRunnable errorLogRunnable = new ProcessLogRunnable(callBack);
            infoLogRunnable.setInputStream(process.getInputStream())
                    .setOpt(OPT)
                    .setInfo(true)
                    .setEndFlag("BUILD SUCCESSFUL")
                    .setIoUtils(new IOUtils());
            Thread thread_info = new Thread(infoLogRunnable);
            errorLogRunnable.setInputStream(process.getErrorStream())
                    .setOpt(OPT)
                    .setInfo(false)
                    .setEndFlag("BUILD FAILED")
                    .setIoUtils(new IOUtils());
            Thread thread_error = new Thread(errorLogRunnable);

            thread_info.start();
            thread_error.start();

            try {
                thread_info.join();
                thread_error.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @Method ProcessLogRunnable
     * @Description ProcessLogRunnable
     * @auther: lzq
     * @date: 2019/8/27 14:21
     */
    private static class ProcessLogRunnable implements Runnable {
        private InputStream inputStream;
        private IOUtils ioUtils;
        private String opt;
        private String endFlag;
        private boolean isInfo = true;
        private IBuildCallBack mCallBack;

        public ProcessLogRunnable(IBuildCallBack callBack) {
            this.mCallBack = callBack;
        }

        public ProcessLogRunnable setInputStream(InputStream inputStream) {
            this.inputStream = inputStream;
            return this;
        }

        public ProcessLogRunnable setIoUtils(IOUtils ioUtils) {
            this.ioUtils = ioUtils;
            return this;
        }

        public ProcessLogRunnable setOpt(String opt) {
            this.opt = opt;
            return this;
        }

        public ProcessLogRunnable setInfo(boolean info) {
            isInfo = info;
            return this;
        }

        public ProcessLogRunnable setEndFlag(String endFlag) {
            this.endFlag = endFlag;
            return this;
        }

        @Override
        public void run() {
            ioUtils.readLN2String(inputStream, new IOListener<String>() {
                @Override
                public void onCompleted(String result) {
                    if (isInfo) {
                        if (result.contains(endFlag)) {
                            mCallBack.onBuildCallBackStatus(true);
                            System.out.println(opt + "成功!");
                        } else {
                            System.out.println(opt + "失败!");
                        }
                    } else {
                        if (result.contains(endFlag)) {
                            mCallBack.onBuildCallBackStatus(false);
                            System.out.println(opt + "失败");
                        }
                    }

                }

                @Override
                public void onLoding(String readedPart, long current, long length) {
                    System.out.println((isInfo ? "info:" : "error") + readedPart);
                }

                @Override
                public void onInterrupted() {
                    mCallBack.onBuildCallBackStatus(false);
                    System.out.println(opt + "失败，过程被打断");

                }

                @Override
                public void onFail(String errorMsg) {
                    mCallBack.onBuildCallBackStatus(false);
                    System.out.println(opt + "失败*" + errorMsg);
                }
            });
        }
    }
}
